#pragma once

#include <string>
#include <vector>
#include <memory>
#include <mutex>
#include <fstream>
#include <chrono>
#include <unordered_map>
#include <thread>
#include <atomic>
#include <condition_variable>
#include <queue>
#include "market_data_types.h"

namespace hft {

/**
 * @brief 市场数据存储接口
 * 
 * 定义市场数据存储的通用接口，可以有不同的实现（文件、数据库等）
 */
class MarketDataStorage {
public:
    virtual ~MarketDataStorage() = default;

    /**
     * @brief 存储市场数据
     * @param data 市场数据消息
     * @return 是否成功
     */
    virtual bool store(const MarketDataMessage& data) = 0;

    /**
     * @brief 批量存储市场数据
     * @param data_list 市场数据消息列表
     * @return 成功存储的数量
     */
    virtual int storeBatch(const std::vector<MarketDataMessage>& data_list) = 0;

    /**
     * @brief 查询历史数据
     * @param symbol 合约代码
     * @param start_time 开始时间
     * @param end_time 结束时间
     * @return 历史数据列表
     */
    virtual std::vector<MarketDataMessage> query(
        const std::string& symbol,
        const std::chrono::system_clock::time_point& start_time,
        const std::chrono::system_clock::time_point& end_time) = 0;

    /**
     * @brief 清理旧数据
     * @param before_time 清理此时间之前的数据
     * @return 清理的记录数
     */
    virtual int cleanup(const std::chrono::system_clock::time_point& before_time) = 0;

    /**
     * @brief 获取存储统计信息
     * @return 存储的记录总数
     */
    virtual uint64_t getStorageStats() const = 0;
};

/**
 * @brief 基于CSV文件的市场数据存储
 */
class CsvMarketDataStorage : public MarketDataStorage {
public:
    /**
     * @brief 构造函数
     * @param base_dir 基础目录，用于存储CSV文件
     * @param flush_interval 刷新间隔（秒），0表示立即刷新
     */
    explicit CsvMarketDataStorage(
        const std::string& base_dir,
        int flush_interval = 5);
    
    ~CsvMarketDataStorage() override;

    bool store(const MarketDataMessage& data) override;
    int storeBatch(const std::vector<MarketDataMessage>& data_list) override;
    std::vector<MarketDataMessage> query(
        const std::string& symbol,
        const std::chrono::system_clock::time_point& start_time,
        const std::chrono::system_clock::time_point& end_time) override;
    int cleanup(const std::chrono::system_clock::time_point& before_time) override;
    uint64_t getStorageStats() const override;

private:
    /**
     * @brief 获取指定日期和合约的文件路径
     * @param symbol 合约代码
     * @param timestamp 时间戳
     * @return 文件路径
     */
    std::string getFilePath(
        const std::string& symbol,
        const std::chrono::system_clock::time_point& timestamp) const;

    /**
     * @brief 确保目录存在
     * @param path 目录路径
     * @return 是否成功
     */
    bool ensureDirectoryExists(const std::string& path) const;

    /**
     * @brief 刷新缓存到文件
     */
    void flushCache();

    /**
     * @brief 刷新线程函数
     */
    void flushThreadFunc();

private:
    std::string base_dir_;
    int flush_interval_;
    std::atomic<uint64_t> total_records_{0};
    
    // 文件缓存
    struct FileCache {
        std::ofstream file;
        std::vector<MarketDataMessage> buffer;
        std::chrono::system_clock::time_point last_flush;
    };
    
    std::unordered_map<std::string, FileCache> file_cache_;
    mutable std::mutex cache_mutex_;
    
    // 刷新线程
    std::thread flush_thread_;
    std::atomic<bool> running_{true};
    std::condition_variable flush_cv_;
    std::mutex flush_mutex_;
};

/**
 * @brief 异步市场数据存储包装器
 * 
 * 将存储操作放入队列中异步执行，避免阻塞市场数据处理线程
 */
class AsyncMarketDataStorage {
public:
    /**
     * @brief 构造函数
     * @param storage 实际的存储实现
     * @param queue_size 队列大小，0表示无限制
     */
    explicit AsyncMarketDataStorage(
        std::shared_ptr<MarketDataStorage> storage,
        size_t queue_size = 10000);
    
    ~AsyncMarketDataStorage();

    /**
     * @brief 存储市场数据
     * @param data 市场数据消息
     * @return 是否成功加入队列
     */
    bool store(const MarketDataMessage& data);

    /**
     * @brief 获取队列大小
     * @return 当前队列中的消息数量
     */
    size_t getQueueSize() const;

    /**
     * @brief 获取存储统计信息
     * @return 存储的记录总数
     */
    uint64_t getStorageStats() const;

    /**
     * @brief 等待队列处理完成
     * @param timeout_ms 超时时间（毫秒），0表示无限等待
     * @return 是否全部处理完成
     */
    bool waitForCompletion(int timeout_ms = 0);

private:
    /**
     * @brief 工作线程函数
     */
    void workerThreadFunc();

private:
    std::shared_ptr<MarketDataStorage> storage_;
    size_t max_queue_size_;
    
    std::queue<MarketDataMessage> data_queue_;
    mutable std::mutex queue_mutex_;
    std::condition_variable queue_cv_;
    
    std::thread worker_thread_;
    std::atomic<bool> running_{true};
    std::atomic<uint64_t> processed_count_{0};
    std::atomic<uint64_t> dropped_count_{0};
};

} // namespace hft